Hello👋 那我們就來延續昨天的分享,今天繼續介紹Mockito
主要是讓我們可以透過Mock的方式去建立類別,並且被注入,讓我們可以專心去寫單元測試,不用為了Bean的相依性而煩惱。
@Mock
:通常會標註在Repo物件上,模擬與資料庫連接的部分@InjectMocks
:如果今天要測試的service裡面有注入dependency classes,這時候我們就可以在此service上面標註@MockBean
: Mockito 會幫我們創建一個假的 mock 對象,替換掉已存在的那個真實的beanwhen
: 測試function中,用來撰寫測試項目該執行的行為assertNotNull
: 驗證結果是否不為空值,如果為空會拋出例外assertNull
: 驗證結果為空值assertEquals
: 驗證預期與實際結果是否相等assertThrows
: 預期拋出 exception我們在這邊用前面的IronService來寫測試當範例 👇
@Service
@Slf4j
public class IronService {
@Autowired
private BookRepo bookRepo;
public Book findBookById(Integer id) throws BadRequestException {
Book book = new Book();
book = bookRepo.findBookByBookId(id);
if(Objects.isNull(book.getBookId())) {
throw new BadRequestException(String.format("Can not find bookId: %d",id ));
} else {
return book;
}
}
}
我們先來寫一個用BookId查詢Book相關資訊的測試 👇
@MockBean
來讓Mockito幫我們把原本的BookRepo替換掉when
來撰寫測試行為,所以 when(bookRepo.findBookByBookId(1)).thenReturn(book1);
代表我們利用BookId查詢Book物件,thenReturn
就代表回傳的結果assertNotNull
: 代表我們預期結果不為空值assertEquals
: 判斷預期跟實際的結果是否相符@RunWith(SpringRunner.class)
@SpringBootTest
public class IronServiceTest {
@MockBean
private BookRepo bookRepo;
@Autowired
private IronService mockIronService;
@Test
public void testGetBookById() throws BadRequestException {
Book book1 = new Book();
book1.setBookId(1);
book1.setName("Hello World");
book1.setAuthor("Winnie");
when(bookRepo.findBookByBookId(1)).thenReturn(book1);
mockIronService.findBookById(1);
assertNotNull(book1);
assertEquals(book1.getBookId(), 1);
assertEquals(book1.getName(), "Hello World");
}
}
接著寫一個用查詢不到Book相關資訊的測試 👇
assertThrows
來預期我們要丟出的例外assertEquals
去比對我們Exception message是否跟我們預期的相同 @Test
public void testGetBookByIdNotFound() throws BadRequestException {
Book book1 = new Book();
when(bookRepo.findBookByBookId(1)).thenReturn(book1);
BadRequestException exception = assertThrows(BadRequestException.class, () -> {
mockIronService.findBookById(1);
});
assertEquals(String.format("Can not find bookId: %d",1), exception.getMessage());
}
我們就可以來試試看執行我們寫的測試,是否順利通過 ~
執行結果 :
我們也可以用昨天跟大家分享的coverage執行看看,接著點回去原本的IronService就可以看到以下畫面,
有綠色的話代表測試有覆蓋到,紅色的話就代表測試沒有覆蓋到
所以我們可以透過撰寫測試來驗證自己的程式邏輯是否正確以外,也可以看出我們把function是不是寫的過度複雜,所以平常要養成好習慣,一起守護我們的程式品質吧